﻿#define _CRT_SECURE_NO_WARNINGS 1



//在屏幕上输出9 * 9乘法口诀表


//第一种方法

//#include <stdio.h>
//int main()
//{
//	// X * X 
//	//第一个X  需要输出 9次，并且提前设置也便于第二个x设置
//	for (int i = 1; i <= 9; i++)
//	{
//		printf("\n");
//		//因为口诀表中 重新开始位置是从X * X开始的 所以 第二个X需要和第一个X的数字保持一致
//		for (int j = 1; j <= i; j++)
//		{
//			printf("%d * %d  ", j, i);
//		}
//	}
//}


//本次难点   int* 所占的字节  
//          int* + 1 所走的字节
int main()
{
	int a = 10;
	int* p = &a;//  此步骤表明将a的地址取出  放入变量p中
	//详细解读
	// 指针变量p 的类型是 (int*) 
	// 而(int) 表明变量指向的对象是int类型    (*)表明p 是指针变量

	//&是取地址操作符  p 是指针变量   指针变量p中存储的是变量a的地址

	//无论你赋什么值 给指针变量  它都会当作地址处理
	printf("%p\n", p);

	//编号 == 指针 == 地址



	char b = 'aw';
	char* p2 = &b;





	int a2 = 10;
	int* p3 = &a2;
	//那么存储现在知道怎么做了，那要使用的话怎么办呢？

	*p3;// (*)解引用操作符  作用：通过找p3中储存的地址,  从而找到原地址(a2)对应的值

	*p3 = 0; //  这里就是p3通过（*） 解引用找到地址,  并且修改a2内容 变为0
	//  ps: 不知有没有小伙伴想到 
	// (&) 可以取地址     (*) 可以解地址 ,那有没有可能他们两个放在一起时就可以互相抵消呢?
	// 答案是可以的 以此处为例： *p3 实际上就是 *&a2   那么结果就是a2 所对应的值  



	//而 众多的指针类型 你或许会认为他们所占的空间不太相同 但实际上他们所占字节是完全相同的
	//原因就与地址线的数量有关
	//在32位环境下  指针变量大小所占字节都是 4个字节
	//在64位环境下  指针变量大小所占字节都是 8个字节
	//指针变量大小 于它类型无关


	//指针类型决定了指针进行解引用操作符的时候访问几个字节,也就是决定了指针有多大权限!


	int a = 0;
	int* pa = &a;
	char* pc = &a;

	printf("pa=%p\n", pa);
	printf("pa+1=%p\n ", pa + 1);
	printf("pc=%p\n", pc);
	printf("pc+1=%p\n", pc + 1);

	//指针类型决定了指针 +1 , -1 向后走几个字节
	// int*  +1  ---> 向后走4个字节
	// char* +1  ---> 向后走1个字节

	//结论：指针的类型决定了指针向前或者向后走⼀步有多大（距离）

	//————————————————————————————————————————————--
	//const用法

















	//普通形式打印arr数组
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}

	//指针形式打印arr数组
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz1 = sizeof(arr1) / sizeof(arr1[0]);
	int j = 0;
	int* p = &arr[0]; //用指针变量 接收 arr数组第一位的地址
	for (j = 0; j < sz1; j++)
	{
		printf("%d ", *p + j);
	}
}